package com.android.plug;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;
import dalvik.system.DexFile;

import android.content.Intent;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {

    public static final String EXTRA_DEX_PATH = "extra.dex.path";
    public static final String EXTRA_CLASS = "extra.class";
    public static final String EXTRA_PACKAGE = "extra.package";
    private DexFile dexFile;
    private Object obj;
    private Method showTextMethod;
    private Method startActivityMethod;
    DexClassLoader classLoader;
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //	DexProxyAct.resource = DexProxyAct.createResources(this);
        setContentView(R.layout.activity_main);
        Button showText = (Button)findViewById(R.id.showText);
        Button showAct  = (Button)findViewById(R.id.showActivity);
        showText.setOnClickListener(this);
        showAct.setOnClickListener(this);
        File optimizedDirectoryFile = getDir("dex", 0) ;

        String  mNativeLibDir =getDir("pluginlib", Context.MODE_PRIVATE).getAbsolutePath();
        classLoader = new DexClassLoader("/mnt/sdcard/DexFileTest.apk", optimizedDirectoryFile.getAbsolutePath(),
                mNativeLibDir, ClassLoader.getSystemClassLoader());

        try {
            String tag="tag";
            Log.e(tag, "11");

            Log.e(tag, "path is "+optimizedDirectoryFile.getAbsolutePath()+" libDir is "+mNativeLibDir);
            //ClassLoader.getSystemClassLoader()
            // 获取Class类的对象的方法之二
            //	dexFile = DexFile.loadDex("file:///android_asset/DexFileTest.apk","/mnt/sdcard/DexFileTest_temp.apk",0);
            //	obj = dexFile.loadClass("com.example.dexfiletest.DexFileTest", null);
            Log.e(tag, "33");
            // Class mLoadClass = classLoader.loadClass("com.example.dexfiletest.DexFileTest");
            Log.e(tag, "44");
            Class mLoadClass = classLoader.loadClass("com.example.dexfiletest.DexFileTest");
            String name = mLoadClass.getName();
            Log.e(tag," mLoadClass.getName(); is "+name);
            Class cls = Activity.class;
            Constructor constructor = mLoadClass.getConstructor(cls);

            obj = mLoadClass.newInstance();
            Log.e(tag, "55");
            //obj = constructor.newInstance();
            //Log.e(tag," obj.getName(); is "+obj.);
            Log.e(tag, "66");
            Log.e(tag, "77");
            //  Class paramTypes[] = this.getParamTypes(cls, "showText");
            showTextMethod = obj.getClass().getDeclaredMethod("showText", Context.class);
            Log.e(tag, "88 "+showTextMethod.getName());
            //  showTextMethod = obj.getClass().getMethod("showText", null);
            //	 paramTypes = this.getParamTypes(cls, "startActivity");
            startActivityMethod = obj.getClass().getDeclaredMethod("startActivity", Activity.class,View.class);
            // showTextMethod = obj.getClass().getMethod("startActivity", null);
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 获取参数类型，返回值保存在Class[]中
     */
    public Class[] getParamTypes(Class cls, String mName) {
        Class[] cs = null;

        /*
         * Note: 由于我们一般通过反射机制调用的方法，是非public方法
         * 所以在此处使用了getDeclaredMethods()方法
         */
        Method[] mtd = cls.getDeclaredMethods();
        for (int i = 0; i < mtd.length; i++) {
            if (!mtd[i].getName().equals(mName)) {    // 不是我们需要的参数，则进入下一次循环
                continue;
            }

            cs = mtd[i].getParameterTypes();
        }
        return cs;
    }
    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        int id = arg0.getId();
        switch (id) {
            case R.id.showActivity:
                try {
                    Log.e("act"," showActivity");
                    startActivityMethod.invoke(obj,MainActivity.this,arg0);
                    Log.e("act"," showActivity1122");
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.e("act"," IllegalArgumentException");
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.e("act"," IllegalAccessException");
                } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.e("act"," InvocationTargetException "+e.getLocalizedMessage());
                }
                break;
            case R.id.showText:
			/*
			try {
				showTextMethod.invoke(obj,MainActivity.this );
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}*/
                Intent intent = new Intent();
                intent.putExtra("plug", true);
                intent.setClass(MainActivity.this, DexProxyAct.class);
                startActivity(intent);
                break;
            default:
                break;
        }
    }


    private void startAct()
    {
        final String pkg = "com.example.dexfiletest";
        //	final String activityName="com.example.dexfiletest.MainActivity";
        final String activityName="com.centerm.touchscreencheck.TouchScreenCheckActivity";
        Intent dlIntent = new Intent();
        // put extra data
        dlIntent.putExtra(EXTRA_CLASS, activityName);
        dlIntent.putExtra(EXTRA_PACKAGE, pkg);
        //    dlIntent.setClass(this, activityClass);
        performStartActivityForResult(this, dlIntent, 1);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        Log.e("result"," requestCode is "+requestCode+" resultCode is "+resultCode);
    }


    private Class<?> loadPluginClass(ClassLoader classLoader, String className) {
        Class<?> clazz = null;
        try {
            clazz = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return clazz;
    }

    private void performStartActivityForResult(Context context, Intent dlIntent, int requestCode) {

        if (context instanceof Activity) {
            ((Activity) context).startActivityForResult(dlIntent, requestCode);
        } else {
            context.startActivity(dlIntent);
        }
    }

}
